package controllers;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

import javax.mail.Session;

import notifiers.Mails;

import models.*;
import play.libs.Mail;
import play.mvc.*;

@With(Secure.class)
public class UserStories extends Controller {

	/**
	 * This method is responsible for viewing the form responsible for creating
	 * a user story. It will find all components and user stories in the project
	 * using the input param.
	 * 
	 * @param projectId
	 *            The project id that will be used when creating the user story
	 */
	public static void index(final long projectId) {
		List<User> users = User.all().fetch();
		Project project = Project.findById(projectId);
		List<Component> comp = project.components;
		List<Component> comp2 = project.components;
		List<ApplicationRole> appRoles = ApplicationRoles.getAll(projectId);
		List<UserStory> allUserStories = UserStory.all().fetch();
		List<UserStory> userStories = new LinkedList<UserStory>();
		for (int i = 0; i < allUserStories.size(); i++) {
			if (comp.contains(allUserStories.get(i).component)) {
				userStories.add(allUserStories.get(i));
			}
		}
		EventType sprintType = EventType.find("byType", "Sprint").first();
		List<Event> allEvents = Event.find("byType", sprintType).fetch();
		Calendar now = Calendar.getInstance();
		/**
		 * This loop will check if the sprint has already started, if started it
		 * will be removed from the render.
		 */
		for (int i = 0; i < allEvents.size(); i++) {
			if (now.after(allEvents.get(i).startDate)) {
				allEvents.remove(i).save();
				i--;
			}
		}
		render(users, comp, comp2, userStories, appRoles, projectId, project,
				allEvents);
	}

	/**
	 * Returns a list of all events associated to this user Story
	 * 
	 * @param story
	 *            the task
	 * @return a list of all events associated to this user story
	 */
	public static List<Event> getUserStoryEvents(UserStory story) {
		Set<Event> events = new HashSet<Event>();
		events.addAll(story.events);
		// Add all events any task of the story is in
		Set<Event> tasksEvents = new HashSet<Event>();
		for (Task task : story.tasks)
			tasksEvents.addAll(task.events);
		// For any event if it contains all tasks of this story, add this event
		for (Event event : tasksEvents)
			if (event.tasks.containsAll(story.tasks))
				events.add(event);
		List<Event> result = new LinkedList<Event>();
		result.addAll(events);
		Event defaultEvent = Events.getDefaultEvent(story.component.project);
		result.remove(defaultEvent);
		return result;
	}

	/**
	 * Method responsible for creating a new user story from the input
	 * parameters. It will then render back the form of creating a new user
	 * story. When the form is submitted it will then connect with the Model
	 * class to instantiate a new object.
	 * 
	 * @param story
	 *            Description of the story
	 * @param effortEstimation
	 *            Value of the effort
	 * @param priority
	 *            Can be "High", "Medium" or "Low"
	 * @param component
	 *            The id of the component to be related to the new user story
	 * @param userStoriesId
	 *            An array of dependent user stories, it contains the id's of
	 *            that stories
	 * @param component_depId
	 *            An array of dependent components, it contains the id's of that
	 *            components
	 * @param appRoleIds
	 *            An array of id's of the application roles
	 * @param projectId
	 *            The project id of which this user story will be related
	 * @param demoId
	 *            A list of id's of the demo entrie(s) associated
	 * @param sprintId
	 *            A list of id's of the sprint(s) associated
	 */
	public static void createStory(String story, double effortEstimation,
			String priority, long component, long[] userStoriesId,
			long[] component_depId, long[] appRoleIds, long projectId,
			long[] demoId, long[] sprintId) {
		// Values taken as input are ID's of the objects, so we have to make an
		// object by searching using those ID's
		Project proj = Project.findById(projectId);
		List<UserStory> allUserStories = UserStory.all().fetch();
		UserStory duplicate = UserStory.find("story", story).first();
		List<UserStory> projectUserStories = new LinkedList<UserStory>();
		for (int i = 0; i < allUserStories.size(); i++) {
			if (proj.components.contains(allUserStories.get(i).component)) {
				projectUserStories.add(allUserStories.get(i));
			}
		}
		// There is a user story with that name
		if (projectUserStories.contains(duplicate)) {
			flash.error("Error - Duplicate Name");
			index(projectId);
		} else {
			long userId = Long.parseLong(session.get("userId"));
			User usr = User.findById(userId);

			if (component == 0) {
				Component defaultComp = Component.find("byNameAndProject",
						"Default component", proj).first();
				component = (Long) defaultComp.getEntityId();
			}
			Component comp = Component.findById(component);
			List<UserStory> userStories = new LinkedList<UserStory>();
			List<Component> components = new LinkedList<Component>();
			List<DemoEntry> listDemoEntries = new LinkedList<DemoEntry>();
			LinkedList<ApplicationRole> appRoles = new LinkedList<ApplicationRole>();
			List<Event> events = new LinkedList<Event>();
			if (userStoriesId != null) {
				for (int i = 0; i < userStoriesId.length; i++) {
					userStories.add((UserStory) UserStory
							.findById(userStoriesId[i]));
				}
			}
			if (sprintId != null) {
				for (int i = 0; i < sprintId.length; i++) {
					events.add((Event) Event.findById(sprintId[i]));
				}
			}
			if (component_depId != null) {
				for (int i = 0; i < component_depId.length; i++) {
					components.add((Component) Component
							.findById(component_depId[i]));
				}
			}
			if (appRoleIds != null) {
				for (int i = 0; i < appRoleIds.length; i++) {
					appRoles.add((ApplicationRole) ApplicationRole
							.findById(appRoleIds[i]));
				}
			} else {
				flash
						.error("Error! You must associate at least 1 application role to the user story!");
				index(projectId);
			}
			if (demoId != null) {
				for (int i = 0; i < demoId.length; i++) {
					listDemoEntries.add((DemoEntry) DemoEntry
							.findById(demoId[i]));
				}
			}
			UserStory createdStory = new UserStory(story, effortEstimation,
					priority, comp, usr, userStories, components,
					listDemoEntries, "NEW", events).save();
			createdStory.appRoles = appRoles;
			createdStory.save();
			if (appRoleIds != null) {
				while (!appRoles.isEmpty()) {
					appRoles.get(0).userStories.add(createdStory);
					appRoles.remove(0).save();
				}
			}
			if (demoId != null) {
				while (!listDemoEntries.isEmpty()) {
					listDemoEntries.get(0).userStory = createdStory;
					listDemoEntries.get(0).save();
					listDemoEntries.remove(0);
				}
			}
			if (sprintId != null) {
				while (!events.isEmpty()) {
					events.get(0).userStories.add(createdStory);
					events.get(0).save();
					events.remove(0);
				}

			}

			/*
			 * Testing Project p=Project.find().first();
			 * deleteProjectUserStories(p);
			 */
			User thisUser = User
					.findById(Long.parseLong(session.get("userId")));
			List<User> toNotify = UserRoleProject
					.find(
							"select urp.user from UserRoleProject urp where urp.role.title= ? and urp.project=?",
							"Scrum Master", Project.findById(projectId))
					.fetch();
			new Log((Long) thisUser.getEntityId(), (Long) createdStory
					.getEntityId(), "User Story", "new user story created",
					projectId, "").save();
			Notifications.notifyAllUsers(toNotify, "New User Story",
					"A new user story was created in project " + proj.name);			
			index((Long) createdStory.component.project.getEntityId());
		}

	}

	/**
	 * That method will return all user stories associated to a specific project
	 * 
	 * @param p
	 *            The project to be searched for the user stories
	 * @return List of all user stories
	 */
	public static List<UserStory> getAllUserStories(Project p) {
		List<Component> componentList = p.components;
		List<UserStory> userStoryList = new LinkedList<UserStory>();
		List<UserStory> allUserStoryList = new LinkedList<UserStory>();
		for (int i = 0; i < componentList.size(); i++) {
			userStoryList = componentList.get(i).userStoriesAssigned;
			for (int j = 0; j < userStoryList.size(); j++) {
				allUserStoryList.add(userStoryList.get(j));
			}
		}
		/*
		 * Debugging for (int i=0 ; i<allUserStoryList.size() ; i++){
		 * ("User Story is: "+allUserStoryList.get(i).story); }
		 */

		// render(allUserStoryList);
		return allUserStoryList;
	}

	/**
	 * Deletes all user stories related to a project
	 * 
	 * @param p
	 *            Project to have it's user stories deleted
	 * @return False
	 */
	public static boolean deleteProjectUserStories(long projectId) {
		Project p = Project.findById(projectId);
		List<UserStory> allUserStories = getAllUserStories(p);
		List<UserStory> dependants = new LinkedList<UserStory>();
		List<UserStory> dependOn = new LinkedList<UserStory>();
		for (int i = 0; i < allUserStories.size(); i++) {
			dependants = allUserStories.get(i).dependants;
			dependOn = allUserStories.get(i).dependOn;
			if (!dependants.isEmpty()) {
				for (UserStory user : dependants) {
					user.dependOn.remove(allUserStories.get(i));
					user.save();
				}
			}
			if (!dependOn.isEmpty()) {
				for (UserStory user : dependOn) {
					allUserStories.get(i).dependOn.remove(user);
					user.dependants.remove(allUserStories.get(i));
				}
			}
			allUserStories.get(i).delete();
		}
		return true;
	}

	/**
	 * Renders all available user stories in a specific project
	 * 
	 * @param projectId
	 *            The project id of which the user stories will be listed
	 */
	public static void listStories(long projectId) {
		Project project = Project.findById(projectId);
		List<Component> comp = project.components;
		List<UserStory> allUserStories = UserStory.all().fetch();
		List<UserStory> userStories = new LinkedList<UserStory>();
		for (int i = 0; i < allUserStories.size(); i++) {
			if (comp.contains(allUserStories.get(i).component)) {
				userStories.add(allUserStories.get(i));
			}
		}
		render(userStories, project);
	}

	/**
	 * Renders the form of editing a user story.
	 * 
	 * @param id
	 *            The id of the user story to be edited
	 */
	public static void show(long id) {
		UserStory userStory = UserStory.findById(id);

		if (Security.checkPermission(
				"Create/edit/Delete User story in my project",
				userStory.component.project)
				|| Security.checkPermission(
						"Edit dependances between user stories",
						userStory.component.project)
				|| Security.checkPermission(
						"edit/set the priority of a user story in my project",
						userStory.component.project)) {
			boolean creator = false;

			if ((Long) userStory.creator.getEntityId() == Long
					.parseLong(session.get("userId"))) {
				creator = true;
			}

			Component comp = userStory.component;
			User user = userStory.creator;
			Project project = userStory.component.project;
			List<UserStory> allUserStories = UserStory.all().fetch();
			List<UserStory> userStories = new LinkedList<UserStory>();
			// Remove the user story from the list of all user stories,
			// as the user story can't depend on itself
			allUserStories.remove(userStory);
			// Loop to add the user stories that are only related to the project
			// viewing
			for (int i = 0; i < allUserStories.size(); i++) {
				if (project.components
						.contains(allUserStories.get(i).component)) {
					userStories.add(allUserStories.get(i));
				}
			}
			List<Component> listOfComponents = project.components;
			List<Component> listOfComponents2 = project.components;
			List<DemoEntry> allDemoEntries = DemoEntry.all().fetch();
			for (int i = 0; i < allDemoEntries.size(); i++) {
				if (allDemoEntries.get(i).userStory != null
						&& allDemoEntries.get(i).userStory != userStory) {
					allDemoEntries.remove(i);
					i--;
				}
			}
			List<ApplicationRole> storyAppRoles = userStory.appRoles;
			EventType sprintType = EventType.find("byType", "Sprint").first();
			List<Event> allEvents = Event.find("byType", sprintType).fetch();
			Calendar now = Calendar.getInstance();

			for (int i = 0; i < allEvents.size(); i++) {
				if (now.after(allEvents.get(i).startDate)) {
					allEvents.remove(i).save();
					i--;
				}
			}

			render(user, comp, userStory, allUserStories, storyAppRoles,
					listOfComponents, listOfComponents2, userStories, creator,
					allDemoEntries, project, allEvents);
		} else {
			forbidden("Access Denied! You are not authorized to view this webpage.");
		}
	}

	/**
	 * Method responsible for editing a user story. After, the form is
	 * submitted, it connects with the Model class to get the user story and
	 * edit it's variables with the new values.
	 * 
	 * @param userStoryId
	 *            Id of the user story to be edited
	 * @param story
	 *            The description of the story
	 * @param effortEstimation
	 *            Value of the effort
	 * @param priority
	 *            Can be "High", "Medium" or "Low"
	 * @param component
	 *            The id of the component to be related to the new user story
	 * @param userStoriesId
	 *            An array of dependent user stories, it contains the id's of
	 *            that stories
	 * @param component_depId
	 *            An array of component Id's, that this user story will be
	 *            dependent on
	 * @param demoId
	 *            A list of id's of the demo entrie(s) associated
	 * @param sprintId
	 *            A list of id's of the sprint(s) associated *
	 */
	public static boolean editStory(long userStoryId, String story,
			double effortEstimation, String priority, long component,
			long[] userStoriesId, long[] component_depId, long[] demoId,
			long[] sprintId) {

		Project project = Project.findById(((UserStory) UserStory
				.findById(userStoryId)).component.project.getEntityId());
		List<UserStory> allUserStories = UserStory.all().fetch();
		UserStory thisStory = UserStory.findById(userStoryId);
		UserStory duplicate = UserStory.find("story", story).first();
		List<UserStory> projectUserStories = new LinkedList<UserStory>();
		for (int i = 0; i < allUserStories.size(); i++) {
			if (project.components.contains(allUserStories.get(i).component)) {
				projectUserStories.add(allUserStories.get(i));
			}
		}
			User editingUser = User.findById(Long.parseLong(session
					.get("userId")));
			boolean canEditStory = Security.checkPermission(
					"Create/edit/Delete User story in my project", project);
			boolean canEditPriority = Security.checkPermission(
					"edit/set the priority of a user story in my project",
					project);
			boolean canEditDependencies = Security.checkPermission(
					"Edit dependances between user stories", project);
			if (canEditStory && canEditDependencies && canEditPriority) {
				editAllStoryDetails(userStoryId, story, effortEstimation,
						priority, component, userStoriesId, component_depId,
						demoId, sprintId);
				flash.success("User Story successfully edited!");
			} else {
				if (canEditStory) {
					editStoryDetails(userStoryId, story, effortEstimation,
							component, component_depId, demoId, sprintId);
				}
				if (canEditPriority) {
					editPriority(userStoryId, priority);
				}
				if (canEditDependencies) {
					editStoryDependencies(userStoryId, userStoriesId);
				}
				if (canEditStory || canEditPriority || canEditDependencies) {
					flash.success("User Story successfully edited!");
				}
			}
			new Notification((Long) thisStory.creator.getEntityId(),
					"User Story Edited", thisStory.story + " was edited by: "
							+ editingUser.userName + "").save();
			new Log((Long) editingUser.getEntityId(), userStoryId,
					"User Story", "edited", (Long) project.getEntityId(), "")
					.save();
		

		return true;
	}

	/**
	 * Sets the stories that are dependent on the current story that is being
	 * edited to all the stories with the ids in the list userStoriesId.
	 * 
	 * @param userStoryId
	 *            The id of the story being edited.
	 * @param userStoriesId
	 *            The ids of the userStories that this story is dependant on.
	 */
	private static void editStoryDependencies(long userStoryId,
			long[] userStoriesId) {
		UserStory storyToEdit = UserStory.findById(userStoryId);
		List<UserStory> dependOn = new LinkedList<UserStory>();
		if (userStoriesId != null) {
			for (int i = 0; i < userStoriesId.length; i++) {
				dependOn.add((UserStory) UserStory.find("id", userStoriesId[i])
						.first());
			}
		}
		storyToEdit.dependOn = dependOn;
		storyToEdit.save();

	}

	/**
	 * Changes all the details of the user story that are given with the new
	 * values.
	 * 
	 * @param userStoryId
	 *            The id of the user story to be edited.
	 * @param story
	 *            The new description of the story.
	 * @param effortEstimation
	 *            The new effort estimation.
	 * @param component
	 *            The component that the story belongs to.
	 * @param component_depId
	 *            The ids of the components that the story depends on.
	 * @param demoId
	 *            The ids of the demo entries associated to the story.
	 */
	private static void editStoryDetails(long userStoryId, String story,
			double effortEstimation, long component, long[] component_depId,
			long[] demoId, long[] sprintId) {
		UserStory storyToEdit = UserStory.findById(userStoryId);
		List<DemoEntry> demoEntries = new LinkedList<DemoEntry>();
		if (demoId != null) {
			for (int i = 0; i < demoId.length; i++) {
				demoEntries.add((DemoEntry) DemoEntry.findById(demoId[i]));
				DemoEntry temp = DemoEntry.findById(demoId[i]);
				temp.userStory = (UserStory) UserStory.find("id", userStoryId)
						.first();
				temp.save();
			}
		} else {
			UserStory temp = UserStory.findById(userStoryId);
			for (int i = 0; i < temp.demos.size(); i++) {
				temp.demos.get(i).userStory = null;
				temp.demos.get(i).save();
			}
		}
		List<Component> components = new LinkedList<Component>();
		if (component_depId != null) {
			for (int i = 0; i < component_depId.length; i++) {
				components.add((Component) Component
						.findById(component_depId[i]));
			}
		}
		List<Event> events = new LinkedList<Event>();
		if (sprintId != null) {
			for (int i = 0; i < sprintId.length; i++) {
				events.add((Event) Event.findById(sprintId[i]));
			}
			List<Event> allEvents = Event.all().fetch();
			while (!allEvents.isEmpty()) {
				if (allEvents.get(0).userStories.contains(storyToEdit)) {
					allEvents.get(0).userStories
							.remove(allEvents.get(0).userStories
									.indexOf(storyToEdit));
					allEvents.remove(0);
				} else {
					allEvents.remove(0);
				}
			}
			while (!events.isEmpty()) {
				events.get(0).userStories.add(storyToEdit);
				events.remove(0);
			}

		}		
		UserStory.editUserStory((UserStory) UserStory.find("id", userStoryId)
				.first(), story, effortEstimation, storyToEdit.priority,
				(Component) Component.find("id", component).first(),
				storyToEdit.dependOn, components, demoEntries, events);
	}

	/**
	 * /** Changes all the details of the user story that are given with the new
	 * values.
	 * 
	 * @param userStoryId
	 *            The id of the user story to be edited.
	 * @param story
	 *            The new description of the story.
	 * @param effortEstimation
	 *            The new effort estimation.
	 * @param component
	 *            The component that the story belongs to.
	 * @param component_depId
	 *            The ids of the components that the story depends on.
	 * @param demoId
	 *            The ids of the demo entries associated to the story.
	 * @param priority
	 *            The new priority to be changed.
	 * @param userStoriesId
	 *            The ids of all the dependent user stories.
	 * @param component_depId
	 *            The ids of all the dependent components.
	 * @param demoId
	 *            The ids of all the demo entries.
	 */
	private static void editAllStoryDetails(long userStoryId, String story,
			double effortEstimation, String priority, long component,
			long[] userStoriesId, long[] component_depId, long[] demoId,
			long[] sprintId) {
		editStoryDetails(userStoryId, story, effortEstimation, component,
				component_depId, demoId, sprintId);
		List<UserStory> dependOn = new LinkedList<UserStory>();
		if (userStoriesId != null) {
			for (int i = 0; i < userStoriesId.length; i++) {
				dependOn.add((UserStory) UserStory.find("id", userStoriesId[i])
						.first());
			}
		}
		UserStory editedStory = UserStory.findById(userStoryId);
		editedStory.dependOn = dependOn;
		editedStory.save();
		editedStory.priority = priority;
		editedStory.save();
	}

	/**
	 * Connects with the UserStory model to retrieve the story and change its
	 * priority. It also notifies the owner of the story with the changes made
	 * by email.
	 * 
	 * @param storyId
	 *            The story id
	 * 
	 * @param priority
	 *            The new value for priority
	 * 
	 * @return boolean - true means the edit was successful, otherwise false. It
	 *         will always return true unless an exception is thrown.
	 */
	public static boolean editPriority(final long storyId, final String priority) {
		// Security.checkAccess(
		// "edit/set the priority of a user story in my project", storyId,
		// UserStory.class.getName());
		UserStory story = UserStory.findById(storyId);
		String oldPriority = story.priority;
		story.priority = priority;
		story.save();
		// User editor = User.findById(Long.parseLong(session.get("userId")));
		// if (!editor.equals(story.creator)) {
		// String message = String.format("Dear " + story.creator.firstName
		// + ",\n " + editor.firstName + " " + editor.lastName
		// + " has edited the priority of a user story you created."
		// + "\nStory: As a/an " + story.appRoles.get(0).name + ", "
		// + story.story + "\nOld Priority: " + oldPriority
		// + "\nNew Priority: " + story.priority);
		// Mail.send("coolsoft@gmail.com", story.creator.email,
		// "User Story Edited", message);
		// new Notification(
		// (Long) story.creator.getEntityId(),
		// "User Story Edited",
		// editor.userName
		// + " has changed the priority of the user story: \"As a/an "
		// + story.appRoles.get(0).name + ", " + story.story
		// + "\"").save();
		// }
		return true;
	}

	/**
	 * @author Rana Ramez this method gets all tasks related to a userstory it
	 *         takes linkedlist of tasks and adds in it the tasks related to
	 *         this userstory
	 * @param task
	 *            linkedlist
	 * @param storyId
	 * @return boolean
	 */
	public static LinkedList<Task> getAssociatedTasks(long storyId) {
		UserStory story = UserStory.findById(storyId);
		LinkedList<Task> task = new LinkedList<Task>();
		for (int i = 0; i < story.tasks.size(); i++) {
			task.add(story.tasks.get(i));
		}
		return task;

	}

	/**
	 * this method to change the story description and notify the creator
	 * 
	 * @param userStoryId
	 *            the id of the changed user story.
	 * @param story
	 *            the new description
	 * @return boolean
	 * @see UserStory, User
	 */
	public static boolean editStoryDescription(String userStoryId, String story) {

		if (story != null && !story.equals("")) {
			UserStory s = UserStory.findById(Long.parseLong(userStoryId));
			s.story = story;
			Security.checkAccess("Edit Story", ((Long) s.getEntityId())
					.longValue(), UserStory.class.getName());
			s.save();
			// log and notify
			long userId = Long.parseLong(session.get("userId"));
			User doneBy = User.findById(userId);
			new Log(userId, (Long) s.getEntityId(),
					(UserStory.class.getName()),
					"change the description of the story to " + s.story, null)
					.save();

			if (!doneBy.getEntityId().equals(s.creator.getEntityId()))

				Mails.notifyStoryEdit(s.creator, doneBy,
						(" changed the description of the story "
								+ s.getEntityId() + " to " + s.story), (Long) s
								.getEntityId());

			new Notification(((Long) s.creator.getEntityId()).longValue(),
					"Edit Story", doneBy.userName
							+ " edited the description through the board");
			// end of notifing.

			return true;
		} else {
			flash.error("Invalid Data");
			return false;
		}
	}

	/**
	 * this method to change the estimated effort of a story.
	 * 
	 * @param userStoryId
	 *            the id of the changed user story.
	 * @param newEffort
	 *            the new estimation
	 * @return boolean
	 * @see UserStory
	 */
	public static boolean editStoryEffort(String userStoryId, String newEffort) {

		double effort;
		try {
			effort = Double.parseDouble(newEffort);
		} catch (Exception e) {
			flash.error("Invalid Data");
			return false;
		}
		if (newEffort != null && !newEffort.equals("")) {
			UserStory s = UserStory.findById(Long.parseLong(userStoryId));
			Security.checkAccess("Edit Story", ((Long) s.getEntityId())
					.longValue(), UserStory.class.getName());
			s.effortEstimation = effort;
			s.save();

			// log and notify
			long userId = Long.parseLong(session.get("userId"));
			User doneBy = User.findById(userId);
			new Log(userId, (Long) s.getEntityId(),
					(UserStory.class.getName()),
					"change the estimated effort of the story to "
							+ s.effortEstimation, null).save();

			if (!doneBy.getEntityId().equals(s.creator.getEntityId()))

				Mails.notifyStoryEdit(s.creator, doneBy,
						(" changed the description of the story "
								+ s.getEntityId() + " to " + s.story), (Long) s
								.getEntityId());

			new Notification(((Long) s.creator.getEntityId()).longValue(),
					"Edit Story", doneBy.userName
							+ " edited the description through the board");
			// end of notifing.

			return true;
		} else {
			flash.error("Invalid Data");
			return false;
		}
	}

	/**
	 * @author Rana Ramez this method gets all tasks related to a userstory it
	 *         takes linkedlist of tasks and adds in it the tasks related to
	 *         this userstory
	 * @param task
	 *            linkedlist
	 * @param storyId
	 * @return boolean
	 */
	public static boolean getAssociatedTasks(List<Task> task, long storyId) {
		UserStory story = UserStory.findById(storyId);
		for (int i = 0; i < story.tasks.size(); i++) {
			task.add(story.tasks.get(i));
		}
		return true;

	}

	/**
	 * returns a list of the user stories assigned to a specific component
	 * 
	 * @param componentId
	 * @return List<UserStory>
	 */
	public static List<UserStory> getComponentStories(Long componentId) {
		Component component = Component.findById(componentId);
		return component.userStoriesAssigned;
	}

	/**
	 * Calls the method deleteUserStory and then redirects to the page of all
	 * user stories.
	 * 
	 * @param storyId
	 *            The id of the story to be deleted.
	 */
	public static void submitDeleteUserStory(long storyId) {
		Security.checkAccess("Create/edit/Delete User story in my project",
				storyId, UserStory.class.getName());
		UserStory story = UserStory.findById(storyId);
		deleteUserStory((Long) story.getEntityId());
		listStories((Long) story.component.project.getEntityId());
	}

	/**
	 * Deletes a user story from the system if it exists and there are no other
	 * stories dependent on it. If it was deleted the method returns true.
	 * Otherwise it returns false.
	 * 
	 * @param story
	 *            The story to be deleted.
	 * @return boolean.
	 */
	public static boolean deleteUserStory(long storyId) {
		UserStory story = UserStory.findById(storyId);
		if (story == null) {
			flash
					.error("The user story you are trying to delete does not exist!");
			return false;
		}
		if (story.dependants.size() != 0) {
			flash
					.error("This user story cannot be deleted because other stories are dependant on it.");
			return false;
		}
		flash
				.success("User story successfully deleted and all its associations removed!");
		story.delete();
		return true;
	}

}